package com.itlong.cloud.utils.export;

import com.itlong.cloud.enumerate.FileCatalogEnum;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 *      导出工具类
 * </desc>
 *
 * @createDate 2019/12/26
 */
public class ExportUtil {

    private final static String EXCELXLS = ".xls"; // 2003- 版本的excel
    private final static String EXCELXLSX = ".xlsx"; // 2007+ 版本的excel

    /**
     * <desc>
     *      通用导出数据信息，无字段(如：数字)转义，若要转义，则传的数据必须已经转好，可在sql查询时直接转
     * </desc>
     *
     * @param eList 要导出的数据
     * @param exportItemNames 导出项中文名即列名，英文逗号连接，不能为空
     * @param exportItems 导出项，字段名，英文逗号连接，不能为空
     * @param rowHeight 行高
     * @param columnWidth 列宽
     * @param fileNameMark 文件名标识符
     * @param FILE_FTP_HOST ftp 域名
     * @param FILE_FTP_USERNAME ftp 用户名
     * @param FILE_FTP_PASSWORD ftp 密码
     * @param FILE_FTP_PORT ftp 端口
     * @param FILE_ACCESS_URL 文件系统访问域名
     * @return 文件路径
     * @author wangzhi
     * @createDate 2019/12/26
     */
    public static <E> String exportByItemsAndNames(List<E> eList, String exportItemNames, String exportItems,
                                               short rowHeight, int columnWidth, String fileNameMark,
                                               String FILE_FTP_HOST, String FILE_FTP_USERNAME, String FILE_FTP_PASSWORD, String FILE_FTP_PORT, String FILE_ACCESS_URL) {
        try {
            //创建excel工作簿
            HSSFWorkbook workbook = new HSSFWorkbook();
            String[] title = StringHandlerUtil.splitString(exportItemNames);
            String[] items = StringHandlerUtil.splitString(exportItems);
            //创建工作表sheet并设置简单格式
            HSSFSheet sheet = workbook.createSheet();
            sheet.setDefaultColumnWidth(columnWidth);
            //创建第一行
            HSSFRow row = sheet.createRow(0);
            row.setHeight(rowHeight);
            HSSFCell cell;
            //插入第一行数据的表头
            for (int i = 0; i < title.length; i++) {
                cell = row.createCell(i);
                cell.setCellValue(title[i]);
            }
            //写入数据
            for (int dataIndex = 0; dataIndex < eList.size(); dataIndex++) {
                E e = eList.get(dataIndex);
                int rowIndex = dataIndex + 1; // 第一行已为标题行
                HSSFRow dataRow = sheet.createRow(rowIndex);
                dataRow.setHeight(rowHeight);

                // 填充数据
                Class clazz = e.getClass();
                for (int i = 0; i < items.length; i++) {
                    if ("serialNum".equals(items[i])) {
                        // 填充序号
                        HSSFCell noteCell = dataRow.createCell(0);
                        noteCell.setCellValue(rowIndex);
                        continue;
                    }
                    cell = dataRow.createCell(i);
                    Object value = ValueUtil.getValueByName(e, clazz, items[i]);
                    cell.setCellValue(value == null ? "" : value.toString());
                }
            }

            String fileName = String.format("%s_ExportDataInfo_%s.xls", fileNameMark, DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS"));
            fileName = URLEncoder.encode(fileName, "UTF-8");
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            workbook.write(os);
            byte[] content = os.toByteArray();
            InputStream exportFileStream = new ByteArrayInputStream(content);
            return uploadFile(exportFileStream, fileName, FILE_FTP_HOST, FILE_FTP_USERNAME, FILE_FTP_PASSWORD, FILE_FTP_PORT, FILE_ACCESS_URL);
        } catch (Exception e) {
            return null;
        }
    }


    /**
     * 描述：根据文件后缀，自适应上传文件的版本
     *
     * @param inStr 输入流
     * @param fileName 文件名
     * @return 对应版本的workbook文件
     * @Author Zhu.yj
     * @createDate 2020/12/28
     */
    public static Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {
        Workbook wb = null;
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        if (EXCELXLS.equals(fileType)) {
            wb = new HSSFWorkbook(inStr); // 2003-
        } else if (EXCELXLSX.equals(fileType)) {
            wb = new XSSFWorkbook(inStr); // 2007+
        } else {
            throw new Exception("解析的文件格式有误！");
        }
        return wb;
    }


    /**
     * <desc>
     *      Ftp上传文件，返回Url.
     * </desc>
     *
     * @param inputStream 文件流
     * @param fileName 文件名称
     * @return 文件上传成功后会返回Url,否则返回空
     * @author wangzhi
     * @createDate 2019/12/26
     */
    private static String uploadFile(InputStream inputStream, String fileName,
                              String FILE_FTP_HOST, String FILE_FTP_USERNAME, String FILE_FTP_PASSWORD, String FILE_FTP_PORT, String FILE_ACCESS_URL) throws IOException {
        String fileUrl = "";
        String fileType = StringHandlerUtil.copySubStr(fileName, fileName.lastIndexOf('.') + 1, fileName.length());
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                inputStream,
                fileType,
                FILE_ACCESS_URL,
                FileCatalogEnum.EXPORT_EXCEL_ZHANG_FILE.getType()
        );
        Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
        Boolean returnCode = (Boolean)resultMap.get("returnCode");
        if (!returnCode){
            return fileUrl;
        }
        fileUrl = resultMap.get("accessPath").toString();
        return fileUrl;
    }

}
